/**
 * WebSocket服务
 * 负责管理WebSocket连接和消息发送
 */
class WebSocketService {
  constructor() {
    this.socket = null;
    this.messageHandlers = new Map();
    this.reconnectAttempts = 0;
    this.reconnectInterval = 3000;
    this.maxReconnectAttempts = 5;
    this.userId = null;
    this.heartbeatInterval = null;
    this.heartbeatTimeout = 15000; // 15秒发送一次心跳
  }

  /**
   * 建立WebSocket连接
   * @param {number} userId 用户ID
   */
  connect(userId) {
    if (this.socket && this.socket.readyState === WebSocket.OPEN) {
      console.log('WebSocket已连接，不需要重新连接');
      return;
    }

    this.userId = userId;
    this.socket = new WebSocket(`ws://localhost:8080/ws/chat?userId=${userId}`);

    this.socket.onopen = () => {
      console.log('WebSocket连接已建立');
      this.reconnectAttempts = 0;
      // 触发连接成功事件
      this.dispatchEvent('open');
      
      // 开始发送心跳包
      this.startHeartbeat();
    };

    this.socket.onmessage = (event) => {
      console.log('WebSocket原始消息:', event.data);
      try {
        const message = JSON.parse(event.data);
        this.handleMessage(message);
      } catch (error) {
        console.error('解析消息失败:', error);
      }
    };

    this.socket.onclose = () => {
      console.log('WebSocket连接已关闭');
      
      // 停止心跳
      this.stopHeartbeat();
      
      // 尝试重连
      this.reconnect();
    };

    this.socket.onerror = (error) => {
      console.error('WebSocket错误:', error);
    };
  }

  /**
   * 开始发送心跳包
   */
  startHeartbeat() {
    // 清除可能存在的旧心跳定时器
    this.stopHeartbeat();
    
    // 设置新的心跳定时器
    this.heartbeatInterval = setInterval(() => {
      if (this.socket && this.socket.readyState === WebSocket.OPEN) {
        console.log('发送心跳包...');
        const heartbeat = {
          type: 'heartbeat',
          timestamp: Date.now()
        };
        this.socket.send(JSON.stringify(heartbeat));
      }
    }, this.heartbeatTimeout);
  }

  /**
   * 停止发送心跳包
   */
  stopHeartbeat() {
    if (this.heartbeatInterval) {
      clearInterval(this.heartbeatInterval);
      this.heartbeatInterval = null;
    }
  }

  /**
   * 重新连接
   */
  reconnect() {
    if (this.reconnectAttempts >= this.maxReconnectAttempts) {
      console.log('达到最大重连次数，停止重连');
      return;
    }

    this.reconnectAttempts++;
    console.log(`尝试重新连接 (${this.reconnectAttempts}/${this.maxReconnectAttempts})...`);
    
    setTimeout(() => {
      if (this.userId) {
        this.connect(this.userId);
      }
    }, this.reconnectInterval);
  }

  /**
   * 发送消息
   * @param {Object} message 消息对象
   */
  sendMessage(receiverId, bookId, content) {
    if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
      console.error('WebSocket未连接，无法发送消息');
      return false;
    }

    // 注意：我们不再需要发送senderId，后端会从token中获取
    const message = {
      receiver_id: receiverId,
      book_id: bookId,
      content: content
    };

    console.log('正在通过WebSocket发送消息:', message);
    this.socket.send(JSON.stringify(message));
    return true;
  }

  /**
   * 注册消息处理器
   * @param {string} type 消息类型
   * @param {Function} handler 处理函数
   */
  on(type, handler) {
    if (!this.messageHandlers.has(type)) {
      this.messageHandlers.set(type, []);
    }
    this.messageHandlers.get(type).push(handler);
  }

  /**
   * 触发事件
   * @param {string} type 事件类型
   * @param {Object} data 事件数据
   */
  dispatchEvent(type, data) {
    if (this.messageHandlers.has(type)) {
      this.messageHandlers.get(type).forEach(handler => handler(data));
    }
  }

  /**
   * 处理接收到的消息
   * @param {Object} message 消息对象
   */
  handleMessage(message) {
    console.log('收到WebSocket消息:', message);
    
    if (message.type) {
      // 触发对应类型的事件
      this.dispatchEvent(message.type, message);
    }
  }

  /**
   * 关闭连接
   */
  disconnect() {
    // 停止心跳
    this.stopHeartbeat();
    
    if (this.socket) {
      this.socket.close();
      this.socket = null;
    }
  }
}

// 创建单例实例
const webSocketService = new WebSocketService();
export default webSocketService; 